/*
 * @Author: lll 1280388921@qq.com
 * @Date: 2025-05-08 22:19:16
 * @LastEditors: lll 1280388921@qq.com
 * @LastEditTime: 2025-05-11 00:51:12
 * @FilePath: /lesson39/2.blockqueue/blockqueue.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include <iostream>
#include <pthread.h>
#include <queue>

using namespace std;

template <class T>
class blockqueue
{
    static const int defaultnum = 20;

public:
    blockqueue(int maxcap = defaultnum)
        : maxcap_(maxcap)
    {
        pthread_mutex_init(&mutex_, nullptr);
        pthread_cond_init(&c_cond_, nullptr);
        pthread_cond_init(&p_cond_, nullptr);
        // low_water=maxcap_/3;
        // high_water=maxcap_*2/3;
    }
    ~blockqueue()
    {
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&c_cond_);
        pthread_cond_destroy(&p_cond_);
    }
    T pop()
    {
        pthread_mutex_lock(&mutex_);
        while(q_.size()==0)//做到防止代码被伪唤醒！
        {
            pthread_cond_wait(&c_cond_,&mutex_);//1.调用的时候，自动释放锁
        }
        T t=q_.front();             // 你想消费，就直接能消费吗?不一定。你得先确保消费条件满足
        q_.pop();
        // if(q_.size()<low_water)pthread_cond_signal(&p_cond_);
        pthread_cond_signal(&p_cond_);//pthread_cond_broadcast
        pthread_mutex_unlock(&mutex_);
        return t;
    }
    void push(const T &in)
    {
        pthread_mutex_lock(&mutex_);
        while(q_.size()==maxcap_)//做到防止代码被伪唤醒！
        {
            pthread_cond_wait(&p_cond_,&mutex_);//1.调用的时候，自动释放锁
        }
        q_.push(in);                // 你想生产，就直接能生产吗?不一定。你得先确保生产条件满足
        // if(q_.size()>high_water)pthread_cond_signal(&c_cond_);
        pthread_cond_signal(&c_cond_);
        pthread_mutex_unlock(&mutex_);

    }

private:
    queue<T> q_;
    int maxcap_;
    // int mincap_;
    pthread_mutex_t mutex_;
    pthread_cond_t c_cond_;
    pthread_cond_t p_cond_;
    // int low_water;
    // int high_water;
};